<?php

declare (strict_types = 1);

namespace app\service\system;

use app\model\system\DictDataModel;
use app\model\system\DictTypeModel;
use owns\auth\User;
use owns\auth\UserAuth;

class DictService
{
    /**
     * 字典类型列表
     * @param array $param
     */
    public function typeList(array $param)
    {
        $map = [];
        // 字典名称
        if($name = $param['name'] ?? '') {
            $map[] = ['name', 'like', trim($name) . '%'];
        }
        // 字典标示
        if($code = $param['code'] ?? '') {
            $map[] = ['code', 'like', trim($code) . '%'];
        }

        $list = DictTypeModel::where($map)
            ->order('sort asc,id desc')
            ->select()->toArray();
        return recursion($list, 0, false, 'parent_id');
    }
    /**
     * 字典类型编辑
     * @param array $data
     * @param integer $id
     */
    public function typeEdit(array $data, int $id): void
    {
        $auth = UserAuth::instance();
        if($id) {
            $dictType = DictTypeModel::find($id);
            if(!$dictType) {
                tips('无字典类型信息，修改失败');
            }
            $dictType->updated_by = $auth->username();
        } else {
            $dictType = new DictTypeModel();
            $dictType->created_by = $auth->username();
        }
        $dictType->parent_id = $data['parent_id']?:0;
        $dictType->name = trim($data['name']);
        $dictType->code = trim($data['code']);
        $this->_dictTypeRepeat($dictType->code, $id);
        $dictType->sort = $data['sort'];
        if(!$dictType->save()) {
            tips('保存失败');
        }
    }
    /**
     * 字典类型code查重
     * @param string $code 字典标示
     * @param integer $id
     */
    private function _dictTypeRepeat(string $code, int $id): void
    {
        $where = DictTypeModel::where('code', $code);
        if($id) {
            $where->where('id', '<>', $id);
        }
        if($where->find()) {
            tips('字典标识【' . $code . '】已被使用');
        }
    }
    /**
     * 字典类型删除
     * @param integer $id
     */
    public function typeDelete(int $id): void
    {
        $dictType = DictTypeModel::where('id', $id)->find();
        if(!$dictType) {
            tips('未找到相关');
        }
        DictTypeModel::where('id', $dictType->id)->delete();
        DictDataModel::where('type_id', $dictType->id)->delete();
        $this->_typeDeleteChildren((int) $dictType->id);
    }
    /**
     * 字典类型子级删除
     * @param integer $parent_id
     */
    private function _typeDeleteChildren(int $parent_id): void
    {
        $typeList = DictTypeModel::where('parent_id', $parent_id)->select();
        if($typeList->isEmpty()) {
            return;
        }
        foreach($typeList as $dictType) {
            DictTypeModel::where('id', $dictType->id)->delete();
            DictDataModel::where('type_id', $dictType->id)->delete();
            $this->_typeDeleteChildren((int) $dictType->id);
        }
    }
    /**
     * 字典数据列表
     * @param array $param
     */
    public function dataList(array $param)
    {
        $map = [];
        // 字典类型ID
        if($typeId = $param['type_id'] ?? '') {
            $map[] = ['type_id', '=', $typeId];
        }
        // 字典标签
        if($label = $param['label'] ?? '') {
            $map[] = ['label', 'like', trim($label) . '%'];
        }
        // 字典值
        if($value = $param['value'] ?? '') {
            $map[] = ['value', 'like', trim($value) . '%'];
        }
        // 字典标示
        if($code = $param['code'] ?? '') {
            $map[] = ['code', 'like', trim($code) . '%'];
        }

        $list = DictDataModel::where($map)
            ->order('sort asc,id desc')
            ->page($param['page'], $param['pageSize'])
            ->select();
        return list_fmt($list, DictDataModel::where($map)->count());
    }
    /**
     * 字典数据编辑
     * @param array $data
     * @param integer $id
     */
    public function dataEdit(array $data, int $id): void
    {
        $auth = UserAuth::instance();
        if($id) {
            $dictData = DictDataModel::find($id);
            if(!$dictData) {
                tips('无字典类型信息，修改失败');
            }
            $dictData->updated_by = $auth->username();
        } else {
            $dictData = new DictDataModel();
            $dictData->created_by = $auth->username();
        }
        $dictData->type_id = $data['type_id'];
        $dictType = DictTypeModel::find($dictData->type_id);
        if(!$dictType) {
            tips('未找到字典类型');
        }
        $dictData->code = $dictType->code;
        $dictData->data_type = $data['data_type'];
        $dictData->label = trim($data['label']);
        $this->_dictDataRepeat($dictData->label, $id);
        $dictData->value = trim($data['value']);
        $dictData->remark = $data['remark'];
        $dictData->sort = $data['sort'];
        if(!$dictData->save()){
            tips('保存失败');
        }
    }
    /**
     * 字典数据label查重
     * @param string $label 键名
     * @param integer $id
     */
    private function _dictDataRepeat(string $label, int $id): void
    {
        $where = DictDataModel::where('label', $label);
        if($id) {
            $where->where('id', '<>', $id);
        }
        if($where->find()) {
            tips('键名【' . $label . '】已被使用');
        }
    }
    /**
     * 字典数据删除
     * @param array $ids
     */
    public function dataDelete(array $ids)
    {
        return DictDataModel::whereIn('id', $ids)->delete();
    }
}